1 /*
2 AntMake
3
4 Copyright (C) 2004 Jose San Leandro Armend?riz
5 jsanleandro@yahoo.es
6 chousz@yahoo.com
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 Thanks to ACM S.L. for distributing this library under the GPL license.
23 Contact info: jsr000@terra.es
24 Postal Address: c/Playa de Lagoa, 1
25 Urb. Valdecaba?as
26 Boadilla del monte
27 28660 Madrid
28 Spain
29
30 ******************************************************************************
31 This class is a customization of CvsChangeLogTask
32 included in Ant distribution, and whose license details
33 are the following.
34
35 *
36 * The Apache Software License, Version 1.1
37 *
38 * Copyright (c) 2002 The Apache Software Foundation. All rights
39 * reserved.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 *
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 *
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in
50 * the documentation and/or other materials provided with the
51 * distribution.
52 *
53 * 3. The end-user documentation included with the redistribution, if
54 * any, must include the following acknowlegement:
55 * "This product includes software developed by the
56 * Apache Software Foundation (http://www.apache.org/)."
57 * Alternately, this acknowlegement may appear in the software itself,
58 * if and wherever such third-party acknowlegements normally appear.
59 *
60 * 4. The names "Ant" and "Apache Software
61 * Foundation" must not be used to endorse or promote products derived
62 * from this software without prior written permission. For written
63 * permission, please contact apache@apache.org.
64 *
65 * 5. Products derived from this software may not be called "Apache"
66 * nor may "Apache" appear in their names without prior written
67 * permission of the Apache Group.
68 *
69 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
70 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
71 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
72 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
73 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
74 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
75 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
76 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
77 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
78 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
79 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80 * SUCH DAMAGE.
81 * ====================================================================
82 *
83 * This software consists of voluntary contributions made by many
84 * individuals on behalf of the Apache Software Foundation. For more
85 * information on the Apache Software Foundation, please see
86 * <http://www.apache.org/>.
87 *
88
89 ******************************************************************************
90 *
91 * Filename: $RCSfile: CvsUtils.java,v $
92 *
93 * Author: Jose San Leandro Armend?riz
94 *
95 * Description: Provides helpful methods for interacting with CVS servers
96 * through its command-line client.
97 *
98 * Last modified by: $Author: chous $ at $Date: 2004/01/31 18:18:58 $
99 *
100 * File version: $Revision: 1.5 $
101 *
102 * Project version: $Name: $
103 *
104 * $Id: CvsUtils.java,v 1.5 2004/01/31 18:18:58 chous Exp $
105 *
106 */
107 package org.acmsl.antmake.cvslib;
108
109 /*
110 * Importing project classes.
111 */
112 import org.acmsl.antmake.AntMakeException;
113 import org.acmsl.antmake.AntMakeUtils;
114 import org.acmsl.antmake.cvslib.ChangeLogParser;
115 import org.acmsl.antmake.cvslib.CvsEntry;
116 import org.acmsl.antmake.cvslib.RcsFile;
117 import org.acmsl.antmake.cvslib.RedirectingStreamHandler;
118
119 /*
120 * Importing ACM-SL Commons classes.
121 */
122 import org.acmsl.commons.utils.StringUtils;
123
124 /*
125 * Importing some Ant classes.
126 */
127 import org.apache.tools.ant.BuildException;
128 import org.apache.tools.ant.DirectoryScanner;
129 import org.apache.tools.ant.Project;
130 import org.apache.tools.ant.Task;
131 import org.apache.tools.ant.taskdefs.Execute;
132 import org.apache.tools.ant.types.Commandline;
133 import org.apache.tools.ant.types.FileSet;
134
135 /*
136 * Importing some JDK classes.
137 */
138 import java.io.BufferedWriter;
139 import java.io.File;
140 import java.io.FileInputStream;
141 import java.io.FileOutputStream;
142 import java.io.IOException;
143 import java.io.OutputStreamWriter;
144 import java.io.PrintWriter;
145 import java.io.UnsupportedEncodingException;
146 import java.lang.ref.WeakReference;
147 import java.text.DateFormat;
148 import java.text.SimpleDateFormat;
149 import java.util.ArrayList;
150 import java.util.Arrays;
151 import java.util.Collection;
152 import java.util.Collections;
153 import java.util.Comparator;
154 import java.util.Date;
155 import java.util.Iterator;
156 import java.util.List;
157 import java.util.Properties;
158
159 /***
160 * Provides helpful methods for interacting with CVS servers
161 * through its command-line client.
162 * @author <a href="mailto:jsanleandro@yahoo.es"
163 >Jose San Leandro</a>, based on
164 * <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> and
165 * <a href="mailto:peter@apache.org">Peter Donald</a>'s
166 * CvsChangeLogTask.
167 * @version $Revision: 1.5 $
168 */
169 public class CvsUtils
170 {
171 /***
172 * The margin.
173 */
174 public static final int MARGIN = 71;
175
176 /***
177 * The date comparator to sort the CVS entries.
178 */
179 public static final Comparator DATE_COMPARATOR =
180 new DateComparator();
181
182 /***
183 * The date format.
184 */
185 public static final DateFormat DATE_FORMAT =
186 new SimpleDateFormat("yyyy-MM-dd");
187
188 /***
189 * Singleton implemented as a weak reference.
190 */
191 private static WeakReference m__Singleton;
192
193 /***
194 * Specifies a new weak reference.
195 * @param utils the utils instance to use.
196 */
197 protected static void setReference(CvsUtils utils)
198 {
199 m__Singleton = new WeakReference(utils);
200 }
201
202 /***
203 * Retrieves the weak reference.
204 * @return such reference.
205 */
206 protected static WeakReference getReference()
207 {
208 return m__Singleton;
209 }
210
211 /***
212 * Retrieves a CvsUtils instance.
213 * @return such instance.
214 */
215 public static CvsUtils getInstance()
216 {
217 CvsUtils result = null;
218
219 WeakReference reference = getReference();
220
221 if (reference != null)
222 {
223 result = (CvsUtils) reference.get();
224 }
225
226 if (result == null)
227 {
228 result = new CvsUtils() {};
229
230 setReference(result);
231 }
232
233 return result;
234 }
235
236 /***
237 * Protected constructor to avoid accidental instantiation.
238 */
239 protected CvsUtils() {};
240
241 /***
242 * Generates a GNU-formatted ChangeLog file.
243 * @param workingDirectory the working directory.
244 * @param output the output file.
245 * @param task an Ant task (for logging, and required by Execute).
246 * @throws AntMakeException if something goes wrong while
247 * executing the cvs command.
248 */
249 public void generateChangeLog(
250 File workingDirectory, String output, Task task)
251 throws AntMakeException
252 {
253 if ( (workingDirectory != null)
254 && (output != null)
255 && (task != null))
256 {
257 AntMakeUtils t_AntMakeUtils = AntMakeUtils.getInstance();
258
259 Commandline t_Command = new Commandline();
260
261 t_Command.setExecutable("cvs");
262 t_Command.createArgument().setValue("log");
263
264 ChangeLogParser t_Parser = new ChangeLogParser();
265
266 RedirectingStreamHandler t_Handler =
267 new RedirectingStreamHandler(t_Parser);
268
269 t_AntMakeUtils.log(
270 task, t_Command.describeCommand(), Project.MSG_VERBOSE);
271
272 Execute t_Execute = new Execute(t_Handler);
273
274 t_Execute.setWorkingDirectory(workingDirectory);
275
276 t_Execute.setCommandline(t_Command.getCommandline());
277
278 t_Execute.setAntRun(task.getProject());
279
280 try
281 {
282 int t_iResultCode = t_Execute.execute();
283
284 if (t_iResultCode == -1)
285 {
286 throw new AntMakeException("Error running cvs log");
287 }
288 }
289 catch (IOException ioException)
290 {
291 t_AntMakeUtils.log(
292 task, ioException.getMessage(), Project.MSG_VERBOSE);
293
294 throw new AntMakeException(
295 "Error running cvs log", ioException);
296 }
297
298 String t_strErrors = t_Handler.getErrors();
299
300 if (t_strErrors != null)
301 {
302 t_AntMakeUtils.log(
303 task, t_strErrors, Project.MSG_ERR);
304 }
305
306 CvsEntry[] t_aEntrySet = t_Parser.getEntrySetAsArray();
307
308 writeChangeLog(output, t_aEntrySet, t_AntMakeUtils, task);
309 }
310 }
311
312 /***
313 * Prints changelog to given output file.
314 * @param output the output file.
315 * @param cvsEntries the entry set to write.
316 * @throws AntMakeException if theres an error writing changelog.
317 */
318 public void writeChangeLog(
319 String output,
320 CvsEntry[] cvsEntries,
321 AntMakeUtils antMakeUtils,
322 Task task)
323 throws AntMakeException
324 {
325 if ( (output != null)
326 && (cvsEntries != null))
327 {
328 Exception t_Exception = null;
329
330 FileOutputStream t_fosOutput = null;
331
332 try
333 {
334 t_fosOutput = new FileOutputStream(output);
335
336 PrintWriter t_pwWriter =
337 new PrintWriter(
338 new BufferedWriter(
339 new OutputStreamWriter(t_fosOutput, "UTF-8")));
340
341 cvsEntries = sortByDate(cvsEntries);
342
343 writeChangeLog(t_pwWriter, cvsEntries);
344 }
345 catch (UnsupportedEncodingException unsupportedEncodingException)
346 {
347 if (antMakeUtils != null)
348 {
349 antMakeUtils.log(
350 task, unsupportedEncodingException.getMessage(), Project.MSG_ERR);
351 }
352
353 t_Exception = unsupportedEncodingException;
354 }
355 catch (IOException ioException)
356 {
357 if (antMakeUtils != null)
358 {
359 antMakeUtils.log(
360 task, ioException.getMessage(), Project.MSG_VERBOSE);
361 }
362
363 if (t_Exception == null)
364 {
365 t_Exception = ioException;
366 }
367 }
368 finally
369 {
370 if (t_fosOutput != null)
371 {
372 try
373 {
374 t_fosOutput.close();
375 }
376 catch (IOException ioException)
377 {
378 if (antMakeUtils != null)
379 {
380 antMakeUtils.log(
381 task,
382 ioException.getMessage(),
383 Project.MSG_VERBOSE);
384 }
385
386 if (t_Exception == null)
387 {
388 t_Exception = ioException;
389 }
390 }
391 }
392
393 if (t_Exception != null)
394 {
395 throw new AntMakeException(
396 "Error writing ChangeLog file", t_Exception);
397 }
398 }
399 }
400 }
401
402 /***
403 * Sorts given CVS entries by date.
404 * @param cvsEntries the CVS entries to sort.
405 * @return the sorted collection.
406 */
407 public CvsEntry[] sortByDate(CvsEntry[] cvsEntries)
408 {
409 List t_lResult = new ArrayList();
410
411 if (cvsEntries != null)
412 {
413 t_lResult = Arrays.asList(cvsEntries);
414
415 Collections.sort(t_lResult, DATE_COMPARATOR);
416 }
417
418 return (CvsEntry[]) t_lResult.toArray(cvsEntries);
419 }
420
421 /***
422 * Writes the changelog.
423 * @param printWriter the printWriter.
424 * @param cvsEntries the CVS entries.
425 * @throws IOException if the write operation fails.
426 */
427 public void writeChangeLog(PrintWriter printWriter, CvsEntry[] cvsEntries)
428 throws IOException
429 {
430 if ( (printWriter != null)
431 && (cvsEntries != null))
432 {
433 for (int t_iEntryIndex = 0;
434 t_iEntryIndex < cvsEntries.length;
435 t_iEntryIndex++)
436 {
437 writeChangeLog(printWriter, cvsEntries[t_iEntryIndex]);
438 printWriter.flush();
439 }
440 }
441 }
442
443 /***
444 * Writes a changelog entry.
445 * @param printWriter the printWriter.
446 * @param cvsEntry the CVS entry.
447 * @throws IOException if the write operation fails.
448 */
449 public void writeChangeLog(PrintWriter printWriter, CvsEntry cvsEntry)
450 throws IOException
451 {
452 if ( (printWriter != null)
453 && (cvsEntry != null))
454 {
455 printWriter.println(
456 DATE_FORMAT.format(cvsEntry.getDate())
457 + " "
458 + cvsEntry.getAuthor());
459
460 Collection t_cRcsFiles = cvsEntry.getRcsFiles();
461
462 if (t_cRcsFiles != null)
463 {
464 String t_strLastFile = "";
465
466 Iterator t_FileIterator =
467 t_cRcsFiles.iterator();
468
469 while ( (t_FileIterator != null)
470 && (t_FileIterator.hasNext()))
471 {
472 t_strLastFile =
473 "\n\t* "
474 + ((RcsFile) t_FileIterator.next()).getName();
475
476 if (t_FileIterator.hasNext())
477 {
478 write(
479 printWriter, t_strLastFile);
480 }
481 }
482
483 write(
484 printWriter,
485 "\n\t" // Added since StringUtils removes them,
486 // but they're still needed for the margin
487 // calculation
488 + StringUtils.getInstance().justify(
489 "\n\t"
490 + t_strLastFile
491 + ": "
492 + cvsEntry.getComment(),
493 "\t",
494 MARGIN));
495
496 printWriter.println();
497 printWriter.println();
498 }
499 }
500 }
501
502 /***
503 * Writes the CVS log message.
504 * @param printWriter the print writer.
505 * @param content the content to write.
506 * @throws IOException if the write operation fails.
507 */
508 public void write(PrintWriter printWriter, String content)
509 throws IOException
510 {
511 if ( (printWriter != null)
512 && (content != null))
513 {
514 printWriter.print(content);
515 }
516 }
517
518 /***
519 * Sorts CVS entries by date.
520 * @author <a href="mailto:jsanleandro@yahoo.es"
521 >Jose San Leandro</a>
522 * @version $Revision: 1.5 $
523 */
524 public static class DateComparator
525 implements Comparator
526 {
527 /***
528 * Compares its two arguments for order.
529 * @param first the first entry.
530 * @param second the second entry.
531 * @return a negative integer, zero, or a positive integer
532 * as the first argument is less than, equal to, or greater
533 * than the second.
534 * @throws ClassCastException if the arguments' types prevent
535 * them from being compared by this Comparator.
536 */
537 public int compare(Object first, Object second)
538 throws ClassCastException
539 {
540 return compare((CvsEntry) first, (CvsEntry) second);
541 }
542
543 /***
544 * Compares given CVS entries by their date.
545 * @param first the first entry.
546 * @param second the second entry.
547 * @return a negative integer or a positive integer
548 * depending on whether the first entry is before or after
549 * the second.
550 */
551 public int compare(CvsEntry first, CvsEntry second)
552 {
553 int result = 0;
554
555 if ( (first != null)
556 && (first.getDate() != null))
557 {
558 if ( (second != null)
559 && (second.getDate() != null)
560 && (second.getDate().after(first.getDate())))
561 {
562 result = 1;
563 }
564 else
565 {
566 result = -1;
567 }
568 }
569 else if ( (second != null)
570 && (second.getDate() != null))
571 {
572 result = 1;
573 }
574
575 return result;
576 }
577
578 /***
579 * Checks if given comparator is semantically equal to this
580 * instance.
581 * @param comparator the comparator to check against.
582 * @return <code>true</code> if both instances are semantically
583 * equal.
584 */
585 public boolean equals(Object comparator)
586 {
587 boolean result = false;
588
589 if ( (comparator != null)
590 && (comparator instanceof DateComparator))
591 {
592 result = true;
593 }
594
595 return result;
596 }
597 }
598 }
599
This page was automatically generated by Maven